import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { getUserInfo, logout as logoutApi, refreshToken as refreshTokenApi, type LoginData } from '@/api/auth'
import { storageManager } from '@/utils/storage'
import type { User } from '@/api/user'

// 登录响应数据类型（统一响应格式中的data字段）
export interface LoginResponse extends LoginData {}

export const useUserStore = defineStore('user', () => {
  // 状态
  const token = ref<string>('')
  const refreshToken = ref<string>('')
  const userInfo = ref<User | null>(null)
  const permissions = ref<string[]>([])
  const roles = ref<string[]>([])

  // 初始化状态标志
  let isInitialized = false
  let isInitializing = false
  // 存储监听器回调，用于清理
  const storageListeners: Map<string, (value: any) => void> = new Map()
  // token 刷新锁
  let refreshingToken = false

  // 验证token是否有效（工具函数）
  const checkTokenValid = (tokenToCheck?: string): boolean => {
    const tokenValue = tokenToCheck || token.value
    if (!tokenValue) return false
    
    try {
      // 解析JWT token的payload部分
      const payload = JSON.parse(atob(tokenValue.split('.')[1]))
      const currentTime = Date.now() / 1000
      
      // 检查是否过期
      return payload.exp > currentTime
    } catch (error) {
      console.error('Token验证失败:', error)
      return false
    }
  }

  // 计算属性
  // 优化：只要有有效的 token 就认为已登录，不强制要求 userInfo
  const isLoggedIn = computed(() => {
    if (!token.value) return false
    // 如果有 token，检查 token 是否有效
    return checkTokenValid()
  })
  const userName = computed(() => userInfo.value?.name || '')
  const userAvatar = computed(() => userInfo.value?.avatar || '')
  const userRole = computed(() => userInfo.value?.roles?.[0] || '')

  // 登录
  const login = async (loginData: LoginResponse) => {
    token.value = loginData.access_token
    if (loginData.refresh_token) {
      refreshToken.value = loginData.refresh_token
    }
    userInfo.value = loginData.user
    permissions.value = loginData.user.permissions || []
    roles.value = loginData.user.roles || []

    // 使用存储管理器保存到本地存储（支持跨页面同步）
    storageManager.setItem('token', loginData.access_token)
    if (loginData.refresh_token) {
      storageManager.setItem('refreshToken', loginData.refresh_token)
    }
    storageManager.setItem('userInfo', loginData.user)
    storageManager.setItem('permissions', permissions.value)
    storageManager.setItem('roles', roles.value)
  }

  // 登出
  const logout = async (callApi: boolean = true) => {
    // 重置初始化标志
    isInitialized = false
    // 重置刷新锁
    refreshingToken = false

    if (callApi) {
      try {
        // 调用登出API
        await logoutApi()
      } catch (error) {
        console.error('登出API调用失败:', error)
        // 即使API调用失败，也要清除本地状态
      }
    }
    
    // 清除状态
    token.value = ''
    refreshToken.value = ''
    userInfo.value = null
    permissions.value = []
    roles.value = []

    // 使用存储管理器清除本地存储（支持跨页面同步）
    storageManager.removeItem('token')
    storageManager.removeItem('refreshToken')
    storageManager.removeItem('userInfo')
    storageManager.removeItem('permissions')
    storageManager.removeItem('roles')
  }

  // 获取用户信息
  const fetchUserInfo = async () => {
    try {
      const response = await getUserInfo()
      // 使用统一响应格式
      if (response.data && response.data.success && response.data.data) {
        userInfo.value = response.data.data
        return response.data.data
      } else if (response.data) {
        // 兼容旧格式
        userInfo.value = response.data as unknown as User
        return response.data as unknown as User
      } else {
        throw new Error('获取用户信息失败：响应数据为空')
      }
    } catch (error) {
      console.error('获取用户信息失败:', error)
      throw error
    }
  }

  // 自动续签token（带锁机制，防止并发刷新）
  const refreshTokenIfNeeded = async (thresholdMinutes: number = 5): Promise<boolean> => {
    // 如果正在刷新，等待完成
    if (refreshingToken) {
      return new Promise<boolean>((resolve) => {
        const checkInterval = setInterval(() => {
          if (!refreshingToken) {
            clearInterval(checkInterval)
            // 刷新完成后，检查 token 是否有效
            resolve(checkTokenValid())
          }
        }, 100)
        // 超时保护，最多等待 5 秒
        setTimeout(() => {
          clearInterval(checkInterval)
          resolve(checkTokenValid())
        }, 5000)
      })
    }

    try {
      const tokenValue = token.value
      if (!tokenValue) {
        console.log('没有token，无需刷新')
        return false
      }

      // 解析token获取过期时间
      const payload = JSON.parse(atob(tokenValue.split('.')[1]))
      const exp = payload.exp * 1000 // 转换为毫秒
      const now = Date.now()
      const timeUntilExpiry = exp - now
      const threshold = thresholdMinutes * 60 * 1000 // 转换为毫秒

      // 如果token已过期或将在指定时间内过期，则刷新
      if (timeUntilExpiry <= threshold) {
        console.log(`Token即将过期或已过期（剩余${Math.round(timeUntilExpiry / 1000 / 60)}分钟），开始刷新`)
        
        const refreshTokenValue = refreshToken.value
        if (!refreshTokenValue) {
          console.log('没有refresh token，无法刷新')
          logout(false)
          return false
        }

        // 设置刷新锁
        refreshingToken = true

        try {
          const response = await refreshTokenApi(refreshTokenValue)
          
          // 检查统一响应格式
          let tokenData: LoginData
          if (response.data && response.data.success && response.data.data) {
            tokenData = response.data.data
          } else {
            // 兼容旧格式
            tokenData = response.data as unknown as LoginData
          }
          
          // 更新token和用户信息
          token.value = tokenData.access_token
          if (tokenData.user) {
            userInfo.value = tokenData.user
            permissions.value = tokenData.user.permissions || []
            roles.value = tokenData.user.roles || []
          }
          
          // 保存到本地存储
          storageManager.setItem('token', tokenData.access_token)
          if (tokenData.user) {
            storageManager.setItem('userInfo', tokenData.user)
            storageManager.setItem('permissions', permissions.value)
            storageManager.setItem('roles', roles.value)
          }
          
          // 如果返回了新的refresh_token，更新它
          if (tokenData.refresh_token) {
            refreshToken.value = tokenData.refresh_token
            storageManager.setItem('refreshToken', tokenData.refresh_token)
          }
          
          console.log('Token刷新成功')
          return true
        } finally {
          // 释放刷新锁
          refreshingToken = false
        }
      }

      console.log('Token仍然有效，无需刷新')
      return true
    } catch (error) {
      console.error('刷新token时出错:', error)
      refreshingToken = false
      logout(false)
      return false
    }
  }

  // 检查权限
  const hasPermission = (permission: string) => {
    // 管理员拥有所有权限
    if (permissions.value.includes('*')) {
      return true
    }
    return permissions.value.includes(permission)
  }

  // 检查角色
  const hasRole = (role: string) => {
    return roles.value.includes(role)
  }

  // 检查多个权限（AND关系）
  const hasAllPermissions = (perms: string[]) => {
    // 管理员拥有所有权限
    if (permissions.value.includes('*')) {
      return true
    }
    return perms.every(perm => permissions.value.includes(perm))
  }

  // 检查多个权限（OR关系）
  const hasAnyPermission = (perms: string[]) => {
    // 管理员拥有所有权限
    if (permissions.value.includes('*')) {
      return true
    }
    return perms.some(perm => permissions.value.includes(perm))
  }

  // 验证token是否有效（公开方法）
  const isTokenValid = (tokenToCheck?: string) => {
    return checkTokenValid(tokenToCheck)
  }

  // 初始化用户状态（从本地存储恢复）- 防止重复初始化
  const initUserState = async () => {
    // 如果正在初始化，等待完成
    if (isInitializing) {
      return new Promise<void>((resolve) => {
        const checkInterval = setInterval(() => {
          if (!isInitializing) {
            clearInterval(checkInterval)
            resolve()
          }
        }, 100)
        // 超时保护
        setTimeout(() => {
          clearInterval(checkInterval)
          resolve()
        }, 5000)
      })
    }

    // 如果已经初始化，只注册监听器（如果还没有注册）
    if (isInitialized) {
      setupStorageListeners()
      return
    }

    isInitializing = true

    try {
      const storedToken = storageManager.getItem<string>('token')
      const storedRefreshToken = storageManager.getItem<string>('refreshToken')
      const storedUserInfo = storageManager.getItem<User>('userInfo')
      const storedPermissions = storageManager.getItem<string[]>('permissions')
      const storedRoles = storageManager.getItem<string[]>('roles')

      if (storedToken) {
        token.value = storedToken
        if (storedRefreshToken) {
          refreshToken.value = storedRefreshToken
        }
        
        // 验证token有效性
        if (checkTokenValid()) {
          // 恢复用户信息
          if (storedUserInfo) {
            userInfo.value = storedUserInfo
          }

          if (storedPermissions) {
            permissions.value = storedPermissions
          }

          if (storedRoles) {
            roles.value = storedRoles
          }

          // 尝试刷新用户信息和token（仅在需要时）
          try {
            // 只有在用户信息不存在时才获取用户信息
            if (!userInfo.value) {
              await fetchUserInfo()
            }
            // 检查是否需要刷新token（不阻塞初始化流程）
            refreshTokenIfNeeded().catch((error) => {
              console.error('初始化时刷新token失败:', error)
              // 不在这里清除状态，因为 token 可能仍然有效
            })
          } catch (error) {
            console.error('刷新用户信息失败:', error)
            // 如果获取用户信息失败，但 token 有效，仍然保持登录状态
            // 只有在 token 也无效时才清除
            if (!checkTokenValid()) {
              logout(false)
            }
          }
        } else {
          // token无效，清除本地存储
          console.log('Token已过期，清除本地存储')
          logout(false)
        }
      }

      // 设置跨页面状态同步监听器
      setupStorageListeners()

      isInitialized = true
    } finally {
      isInitializing = false
    }
  }

  // 设置存储监听器（避免重复注册）
  const setupStorageListeners = () => {
    // 清理旧的监听器（如果存在）
    cleanupStorageListeners()

    // token 监听器
    const tokenListener = (newToken: string | null) => {
      if (newToken && newToken !== token.value) {
        token.value = newToken
      } else if (!newToken && token.value) {
        // 其他页面登出，同步清除当前页面状态
        token.value = ''
        refreshToken.value = ''
        userInfo.value = null
        permissions.value = []
        roles.value = []
      }
    }
    storageManager.addListener('token', tokenListener)
    storageListeners.set('token', tokenListener)

    // refreshToken 监听器
    const refreshTokenListener = (newRefreshToken: string | null) => {
      if (newRefreshToken && newRefreshToken !== refreshToken.value) {
        refreshToken.value = newRefreshToken
      } else if (!newRefreshToken && refreshToken.value) {
        refreshToken.value = ''
      }
    }
    storageManager.addListener('refreshToken', refreshTokenListener)
    storageListeners.set('refreshToken', refreshTokenListener)

    // userInfo 监听器
    const userInfoListener = (newUserInfo: User | null) => {
      if (newUserInfo) {
        userInfo.value = newUserInfo
      } else if (!newUserInfo && userInfo.value) {
        userInfo.value = null
      }
    }
    storageManager.addListener('userInfo', userInfoListener)
    storageListeners.set('userInfo', userInfoListener)

    // permissions 监听器
    const permissionsListener = (newPermissions: string[] | null) => {
      if (newPermissions) {
        permissions.value = newPermissions
      } else if (!newPermissions && permissions.value.length > 0) {
        permissions.value = []
      }
    }
    storageManager.addListener('permissions', permissionsListener)
    storageListeners.set('permissions', permissionsListener)

    // roles 监听器
    const rolesListener = (newRoles: string[] | null) => {
      if (newRoles) {
        roles.value = newRoles
      } else if (!newRoles && roles.value.length > 0) {
        roles.value = []
      }
    }
    storageManager.addListener('roles', rolesListener)
    storageListeners.set('roles', rolesListener)
  }

  // 清理存储监听器
  const cleanupStorageListeners = () => {
    storageListeners.forEach((listener, key) => {
      storageManager.removeListener(key, listener)
    })
    storageListeners.clear()
  }

  // 更新用户信息
  const updateUserInfo = (newUserInfo: Partial<User>) => {
    if (userInfo.value) {
      userInfo.value = { ...userInfo.value, ...newUserInfo }
      storageManager.setItem('userInfo', userInfo.value)
    }
  }

  return {
    // 状态
    token,
    refreshToken,
    userInfo,
    permissions,
    roles,
    
    // 计算属性
    isLoggedIn,
    userName,
    userAvatar,
    userRole,
    
    // 方法
    login,
    logout,
    fetchUserInfo,
    hasPermission,
    hasRole,
    hasAllPermissions,
    hasAnyPermission,
    initUserState,
    updateUserInfo,
    isTokenValid,
    refreshTokenIfNeeded
  }
})